home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / faxd / Getty.c++ < prev    next >
C/C++ Source or Header  |  1994-08-01  |  5KB  |  195 lines

  1. /*    $Header: /usr/people/sam/fax/faxd/RCS/Getty.c++,v 1.24 1994/02/28 14:15:22 sam Rel $ */
  2. /*
  3.  * Copyright (c) 1990, 1991, 1992, 1993, 1994 Sam Leffler
  4.  * Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11.  * publicity relating to the software without the specific, prior written
  12.  * permission of Sam Leffler and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. #include "Getty.h"
  26. #include "UUCPLock.h"
  27.  
  28. #include <stdarg.h>
  29. #include <termios.h>
  30. #include <osfcn.h>
  31. #include <signal.h>
  32. #include <syslog.h>
  33. #include <paths.h>
  34. #include <sys/param.h>
  35. #include <sys/stat.h>
  36.  
  37. /*
  38.  * FAX Server Getty Support Base Class.
  39.  */
  40.  
  41. const fxStr Getty::getty = _PATH_GETTY;
  42.  
  43. Getty::Getty(const fxStr& l, const fxStr& s, u_int t)
  44.     : line(l)
  45.     , speed(s)
  46. {
  47.     pid = 0;
  48.     timeout = t;
  49. }
  50.  
  51. Getty::~Getty()
  52. {
  53. }
  54.  
  55. void Getty::setTimeout(u_int t)        { timeout = t; }
  56.  
  57. static void
  58. sigHUP(int)
  59. {
  60.     (void) close(0);
  61.     (void) close(1);
  62.     (void) close(2);
  63.     sleep(5);
  64.     _exit(1);
  65. }
  66.  
  67. /*
  68.  * Parse the getty argument string and
  69.  * substitute runtime parameters:
  70.  *
  71.  *    %l    tty device name
  72.  *    %s    current baud rate
  73.  *
  74.  * The resultant argv array is used to
  75.  * exec getty below.
  76.  */
  77. void
  78. Getty::setupArgv(const char* args)
  79. {
  80.     argbuf = args;
  81.     u_int l;
  82.     /*
  83.      * Substitute escape sequences.
  84.      */
  85.     for (l = 0; l < argbuf.length();) {
  86.     l = argbuf.next(l, '%');
  87.     if (l >= argbuf.length()-1)
  88.         break;
  89.     switch (argbuf[l+1]) {
  90.     case 'l':            // %l = tty device name
  91.         argbuf.remove(l,2);
  92.         argbuf.insert(line, l);
  93.         l += line.length();        // avoid loops
  94.         break;
  95.     case 's':            // %s = tty speed
  96.         argbuf.remove(l,2);
  97.         argbuf.insert(speed, l);
  98.         l += speed.length();    // avoid loops
  99.         break;
  100.     case '%':            // %% = %
  101.         argbuf.remove(l,1);
  102.         break;
  103.     }
  104.     }
  105.     /*
  106.      * Crack argument string and setup argv.
  107.      */
  108.     argv[0] = &getty[getty.nextR(getty.length(), '/')];
  109.     u_int nargs = 1;
  110.     for (l = 0; l < argbuf.length() && nargs < GETTY_MAXARGS-1;) {
  111.     l = argbuf.skip(l, " \t");
  112.     u_int token = l;
  113.     l = argbuf.next(l, " \t");
  114.     if (l > token) {
  115.         if (l < argbuf.length())
  116.         argbuf[l++] = '\0';        // null terminate argument
  117.         argv[nargs++] = &argbuf[token];
  118.     }
  119.     }
  120.     argv[nargs] = NULL;
  121. }
  122.  
  123. /*
  124.  * Run a getty session and if successful exec the
  125.  * getty program.  Note that this is always run in
  126.  * the child.  We actually fork again here so that
  127.  * we immediately reap the real getty and cleanup
  128.  * state.  It also simplifies matters of uid management
  129.  * since the fax server runs as effective uid other
  130.  * than root, but we're started up with real&effective
  131.  * uid root.
  132.  */
  133. void
  134. Getty::run(int fd, const char* args)
  135. {
  136.     pid = fork();
  137.     if (pid == -1)
  138.     fatal("getty: can not fork reaper process");
  139.     closelog();
  140.     openlog("FaxGetty", LOG_PID, LOG_AUTH);
  141.     if (chdir("/dev") < 0)
  142.     fatal("chdir: %m");
  143.     if (pid == 0) {            // child, exec getty
  144.     signal(SIGHUP, fxSIGHANDLER(sigHUP));
  145.     setupArgv(args);
  146.     /*
  147.      * After the session is properly setup, the
  148.      * stdio streams will be hooked to the tty
  149.      * and we can discard the file descriptor.
  150.      */
  151.     setupSession(fd);
  152.  
  153.     char* envp[1];
  154.     envp[0] = NULL;
  155.     execve((char*) getty, argv, envp);
  156.     _exit(127);
  157.     } else {                // parent, wait for getty/login
  158.     close(fd);            // close so HUPCL works correctly
  159.     int status;
  160.     wait(status, TRUE);        // wait for getty/login work to complete
  161.     hangup();
  162.     _exit(status);            // pass exit status upward
  163.     }
  164. }
  165.  
  166. void
  167. Getty::hangup()
  168. {
  169.     chown(getLine(), UUCPLock::getUUCPUid(), UUCPLock::getUUCPGid());
  170.     chmod(getLine(), 0600);        // reset protection
  171. }
  172.  
  173. void
  174. Getty::error(const char* va_alist, ...)
  175. #define    fmt va_alist
  176. {
  177.     va_list ap;
  178.     va_start(ap, fmt);
  179.     vsyslog(LOG_ERR, fmt, ap);
  180.     va_end(ap);
  181. }
  182. #undef fmt
  183.  
  184. void
  185. Getty::fatal(const char* va_alist, ...)
  186. #define    fmt va_alist
  187. {
  188.     va_list ap;
  189.     va_start(ap, fmt);
  190.     vsyslog(LOG_ERR, fmt, ap);
  191.     va_end(ap);
  192.     hangup();
  193. }
  194. #undef fmt
  195.